LexEdge · HermesLegal Workflow Lab · Vol II
v2.0 · workflows 11–20

The second ten

Ten more workflows, and the discipline to run twenty

Volume I got Hermes talking to n8n and gave the firm ten working tools. This volume adds ten that cover what the first set left on the table — deadlines, billing, bundles, compliance and monitoring — and sets the rules that keep a twenty-tool gateway from turning into a guessing game.

Builds on
Vol I · workflows 01–10
New tools
10 (11–20)
Buildable today
6 of 10
Needs a data vendor
4 of 10
Hermes picks 1 of 20 MCP Gateway one door, many tools Matter ops 01 03 04 06 · 19 Contracts 02 09 · 13 14 15 Compliance 08 10 · 12 17 18 Practice ops 05 07 · 11 16 20 four families one naming rule

Orientation

What the first ten left out

Volume I covered the work a lawyer starts: opening a matter, triaging a contract, drafting a reply, researching a question. Look at the set as a whole and one pattern stands out — almost every tool fires because a human asked it to, right now, about one document.

The work that actually leaks time is the other kind: the recurring, the cumulative, and the mechanical. Deadlines that must be computed and then remembered for months. Time that must be written up on Friday for work done on Monday. Obligations buried in a contract that was signed two years ago. A 486-page paperbook that a junior assembles by hand the night before a hearing. None of that is hard. All of it is expensive.

So these ten lean deliberately in three directions the first set didn't:

  • Deterministic, not generative. Four of them (12, 18, 19, and the diff half of 14) do their real work in Code nodes with zero model involvement. Dates and pagination are not creative tasks.
  • Continuous, not on-demand. Two of them (11, 20) run on a schedule and also expose as tools, so Hermes can ask "what changed?" between runs.
  • Cumulative, not per-document. Several operate over a whole matter, a whole data room, or a whole week of activity rather than one file.
The dividing line still holds

Everything in Volume I's orientation section applies unchanged. Hermes reasons and talks; n8n moves data and waits. What changes at twenty tools is not the architecture — it's how carefully you have to name things. See Running twenty tools.

Before you start

Data access, honestly

Four of the ten below want data that lives on Indian government portals — case status and cause lists, MCA/ROC filing histories, GST records, entity and director data. It is worth being blunt about this before you sink a weekend into it.

There is no clean, official, freely available API for most of it. The portals are built for humans: they use captchas, session tokens and rate limits, and their terms of use generally prohibit automated access. Automating them directly is fragile at best and a compliance problem at worst — and a workflow that breaks silently on a hearing date is worse than no workflow.

Three legitimate routes

RouteWhat it looks likeGood for
Licensed data provider A paid API from a legal-data or KYC vendor. Stable schema, SLA, contractual right to use. 11, 17, 18, 20 — anything you'll depend on daily.
Human-in-the-loop upload A clerk downloads the PDF; the workflow takes over from the file. Volume I's WF10 already works this way. Low-volume, high-value documents. Zero access risk.
Official bulk/open data Published judgment corpora, gazette feeds, open datasets where they genuinely exist. 20, and enriching WF5's research store.
Do not automate around a captcha

If a portal presents a captcha, that is the operator telling you automated access is not permitted. Route the step to a human instead — every workflow below that touches external data is designed to degrade into a task for a person rather than push through.

Each card below is tagged build today or needs data vendor so you can plan around it.

The catalogue

The second ten

Same format as Volume I: what a lawyer says, the pipeline, the JSON in and out, build notes, and the guardrail that keeps each one safe. Grey chips in a pipeline mean no model involved — deterministic code.

11

Case Status & Cause List Monitor

Watch every active case for listings, date changes and new orders — and say only what changed.

track_case_statusneeds data vendor
Lawyer"Anything listed for us this week?"
schedule 06:00 active case list query provider diff vs last seen update calendar alert owner

Input

{
  "scope": "all_active",
  "days_ahead": 7
}

Output

{
  "status": "success",
  "cases_checked": 48,
  "listed": 6,
  "date_changed": 2,
  "stale": 3
}
Build notes
  1. Two triggers, one logic path: a Schedule Trigger for the daily sweep and an Execute Sub-workflow Trigger so Hermes can ask on demand.
  2. Store a content hash per case. Alert on change, never on existence — a monitor that reports 48 unchanged cases every morning gets muted in a week, and then it's useless.
  3. Write each check to a log table with a timestamp, so "we didn't know" is always answerable.
  4. Push confirmed listings into the firm calendar; let 12 own the reminder cascade rather than duplicating it here.

GuardrailIf the provider errors or returns nothing for a case, count it in stale and surface it. A monitor must never let silence look like "all clear".

12

Limitation & Deadline Calculator

Compute a statutory deadline from an event, then own the reminders until it passes.

compute_deadlinesbuild today
Lawyer"When does limitation run out on this cheque bounce?"
event + date rule lookup compute window holidays & exclusions write to calendar schedule reminders

Input

{
  "event": "cheque_dishonour",
  "event_date": "2026-06-14",
  "matter_id": "MAT-1002"
}

Output

{
  "status": "success",
  "rule": "NI Act s.138",
  "notice_due": "2026-07-14",
  "window_ends": "2026-09-14",
  "verify_with_counsel": true
}
Build notes
  1. A versioned rules table (Postgres) maps event → statute, period, and the clock's start point. A Code node does the arithmetic against a court-holiday calendar.
  2. No LLM in the计算 path. The model may phrase the answer; it must never produce the date. Hallucinating a limitation period costs a client their claim.
  3. Unknown event type → return "status":"unsupported" with the list of events you do handle. Never guess a rule.
  4. Cascade reminders at 30 / 14 / 7 / 2 days to the owning lawyer, escalating to the supervising partner at 2.

GuardrailEvery response carries verify_with_counsel: true and cites the rule version used. The tool computes; it does not advise.

13

Obligation Register

Read an executed contract and turn its promises into tracked, dated rows.

extract_obligationsbuild today
Lawyer"What are we on the hook for under the ABC master services agreement?"
executed contract extract text AI clause extraction normalise dates write register renewal reminders

Input

{
  "document_url": "...",
  "matter_id": "MAT-1002"
}

Output

{
  "status": "success",
  "obligations": 14,
  "renewal_date": "2027-04-01",
  "notice_days": 60,
  "auto_renew": true
}
Build notes
  1. The natural sequel to Volume I's WF2: triage handles contracts coming in; this handles contracts already signed.
  2. Ask the model for obligations as an array with party, duty, trigger, due, and a clause_ref — the clause reference is what makes a row auditable.
  3. Feed every extracted date through 12 so one component owns reminders firm-wide.
  4. Auto-renewal traps are the single highest-value thing here: a missed 60-day notice window renews a bad contract for a year.

GuardrailAny obligation the model can't tie to a clause reference is written with "confidence":"low" and queued for human confirmation before it drives a reminder.

14

Redline Comparison

Diff two contract versions mechanically, then explain only what actually changed.

compare_contract_versionsbuild today
Lawyer"What did they change in v3?"
two versions extract both paragraph diff AI characterises changes score vs playbook deviation report

Input

{
  "our_version_url": "...",
  "their_version_url": "...",
  "playbook": "vendor_msa"
}

Output

{
  "status": "success",
  "changes": 23,
  "material": 5,
  "off_playbook": 2,
  "recommend": "legal_review"
}
Build notes
  1. Diff first in a Code node at paragraph level. Send only the changed spans to the model — cheaper, faster, and structurally unable to invent a change that isn't in the document.
  2. The model's job is characterisation only: is this change material, and which way does it cut?
  3. Score each material change against the playbook clause positions you already encoded for WF2. Two deviations from the same playbook, one source of truth.
  4. Output a side-by-side report with clause references, not a prose summary. Lawyers want to see the words.

GuardrailIt recommends a lane; it never accepts a change. recommend is advice to a human, and the report always includes the raw diff.

15

Due Diligence Sweep

First-pass a whole data room: classify, extract, flag, and say what it couldn't read.

run_dd_reviewbuild today
Lawyer"Run a first-pass diligence on the XYZ data room."
folder list files classify each extract key terms flag red items checklist + memo

Input

{
  "folder_url": "...",
  "deal_type": "share_purchase",
  "matter_id": "MAT-1044"
}

Output

{
  "status": "partial",
  "documents": 312,
  "classified": 298,
  "unreadable": 14,
  "red_flags": 7
}
Build notes
  1. Use Loop Over Items with a capped batch size, and set a per-item timeout — a real data room will rate-limit you otherwise.
  2. Checkpoint progress to a table as you go, so a failure at document 280 doesn't cost you the first 279.
  3. Red-flag rules come from the deal-type descriptor: change-of-control clauses, unassigned IP, related-party debt, litigation exposure.
  4. Budget it. At 312 documents this is the most expensive tool in the set — log token cost per run from day one.

GuardrailReturns "partial", not "success", whenever anything was unreadable. A sweep that quietly skips 14 files is more dangerous than no sweep at all.

16

Time Capture & Billing Narrative

Reconstruct last week's billable work from calendar, mail and document activity.

generate_time_entriesbuild today
Lawyer"Write up my time for last week."
user + date range calendar + sent mail + docs group by matter AI drafts narratives draft entries lawyer approves

Input

{
  "user": "R. Shah",
  "from": "2026-07-13",
  "to": "2026-07-19"
}

Output

{
  "status": "success",
  "entries_drafted": 22,
  "hours": 31.5,
  "unassigned_hours": 2.0,
  "review_url": "..."
}
Build notes
  1. Highest and fastest return on this list. Recovered write-offs pay for the entire stack inside a quarter.
  2. Signals: calendar events, sent mail threads, document edit history, and n8n's own execution log (WF03 drafted a notice on Tuesday — that's billable time).
  3. The model writes the narrative, not the duration. Duration comes from event length or the lawyer.
  4. Anything it can't attribute lands in unassigned_hours for the lawyer to place — never guess a matter number onto a bill.

GuardrailEverything is a draft in a review queue. The workflow never posts a time entry, never submits a bill, and never touches an invoice a client can see.

17

Client KYC & Engagement

Verify who a prospective client actually is, score the risk, and prepare the engagement letter.

run_client_kycneeds data vendor
Lawyer"Onboard XYZ Corp — run the checks and get the engagement letter ready."
entity details verify PAN / GSTIN / CIN sanctions + adverse media risk score generate letter route for signature

Input

{
  "entity_name": "XYZ Corp",
  "cin": "U72200GJ...",
  "matter_type": "Commercial"
}

Output

{
  "status": "success",
  "verified": true,
  "risk": "low",
  "adverse_hits": 0,
  "letter_url": "..."
}
Build notes
  1. Pairs with Volume I's WF8: conflict check asks may we act, KYC asks who are they. Both run before a matter opens; 01 should refuse to create a matter until both have passed.
  2. Pull the director/shareholder list too — beneficial ownership is where onboarding risk usually hides.
  3. Adverse media search feeds the model raw results; it summarises and cites, it does not judge.
  4. Retain the evidence: every verification response, timestamped, in the matter file. That record is the point of the exercise.

GuardrailAny adverse hit or failed verification sets "requires_review":true, routes to compliance, and blocks letter generation. The workflow can flag a client; it can never clear one.

18

Corporate Compliance Calendar

Track statutory filings across every corporate client entity, and flag what's slipping.

check_roc_complianceneeds data vendor
Lawyer"What's due for our company clients this quarter?"
entity list fetch filing history map to obligations compute due dates flag overdue client digest

Input

{
  "client_id": "CL-220",
  "period": "Q2_FY27"
}

Output

{
  "status": "success",
  "entities": 3,
  "upcoming": 11,
  "overdue": 1,
  "next_due": "AOC-4 / 2026-10-30"
}
Build notes
  1. Secretarial work is calendar-shaped and rule-shaped — exactly what deterministic automation is good at. Same discipline as 12: obligations in a versioned table, dates in a Code node.
  2. Key the obligation set off entity type and size thresholds, not off a flat list. A small private company and a listed one owe different things.
  3. Overdue items are the valuable output. Surface them first and separately from upcoming ones.
  4. Route reminders through 12 rather than building a second reminder engine.

GuardrailIt reports status only — it never files anything, and it never asserts compliance. Absence of a record means "not found", which it reports as such.

19

Court Bundle Builder

Assemble a paginated, indexed, court-ready bundle from a matter's documents.

build_court_bundlebuild today
Lawyer"Prepare the paperbook for MAT-1002."
matter + doc list normalise to PDF order chronologically paginate + stamp generate index save + bookmark

Input

{
  "matter_id": "MAT-1002",
  "bundle_type": "paperbook",
  "include": ["pleadings", "annexures"]
}

Output

{
  "status": "success",
  "bundle_url": "...",
  "pages": 486,
  "missing": 1
}
Build notes
  1. Zero AI, pure mechanics — and it still saves a junior an entire evening. That combination makes it the easiest win to justify.
  2. One Code node owns pagination and the index, so the two can never drift apart. An index that's off by two pages is worse than no index.
  3. Normalise everything to PDF first (scans, Word, images), then stamp. Keep the stamp position configurable per court.
  4. Feed it from WF04's hearing brief so the bundle and the brief reference the same page numbers.

GuardrailMissing or corrupt source documents are listed by name in the response, never skipped silently. Filing an incomplete bundle is a professional problem, not a technical one.

20

Regulatory & Judgment Watch

Scan what's new, keep only what touches a live matter, and say whose.

run_regulatory_watchneeds data vendor
Lawyer"Anything this week I should know about for my GST clients?"
practice areas new judgments + circulars filter relevance map to matters AI digest email

Input

{
  "practice_areas": ["gst", "company_law"],
  "since": "2026-07-15"
}

Output

{
  "status": "success",
  "scanned": 142,
  "relevant": 9,
  "matters_affected": 4,
  "digest_url": "..."
}
Build notes
  1. The mapping step is the whole point. A generic legal-update newsletter is noise; "this circular affects three of your open matters" is advice.
  2. Embed each new item and match against the matter/issue store you built for WF05 — same vector store, second use.
  3. Tune for precision over recall. Nine relevant items get read; forty-five do not.
  4. Every digest entry links to the primary source. A summary of a judgment is a starting point, never a citation.

GuardrailThe digest goes to the firm, never to clients. Whether a development is worth telling a client about is a judgement call — that stays with the lawyer.

Sequencing

Build order

Don't build these in numerical order. Build them in order of what pays back soonest and depends least on anyone else.

WaveBuildWhy nowEffort
First 16 19 12 Immediate, measurable time recovery. No external dependency, minimal AI risk, and 19 is almost pure code. ~2 days each
Second 13 14 Extend the contract pipeline — you already built the extract-and-classify half for WF02, and the playbook is already encoded. ~3 days each
Third 17 18 11 20 Blocked on data access. Scope and contract the vendor first, build second — the workflow is the easy part. vendor-led
Last 15 Highest volume, highest cost per run, most ways to fail halfway. Build it once batching, checkpointing and cost logging are proven elsewhere. ~1 week
Build 12 early even though it's third by value

Three other workflows (11, 13, 18) want to schedule reminders. If each builds its own, you get three reminder engines and three sets of bugs. Ship 12 first and have the others call it.

Discipline

Running twenty tools

At ten tools, Hermes picks correctly almost by accident — the options are far apart. At twenty, near-misses start to matter, and the failure is quiet: the wrong tool runs, returns a plausible result, and nobody notices.

Name against the neighbours, not in isolation

Volume I's advice was to write descriptions in the lawyer's language. That's still right, but it's no longer sufficient. Three of these new tools are about dates, and to a model skimming twenty descriptions they blur together. Write each one to be distinguishable from its nearest sibling:

ToolDescription that separates it
compute_deadlinesCalculates a statutory deadline from a legal event — limitation, notice period, appeal window. Input is an event and its date.
check_roc_complianceReports corporate filing obligations for client entities — ROC forms, annual returns. Input is a client or entity.
track_case_statusReports court listings and hearing dates for active litigation. Input is a case or the whole active docket.
run_regulatory_watchReports new law — judgments and circulars published since a date. Input is a practice area.

Each one names its input type and its subject in the first clause. That's what makes them separable.

Four rules that hold at twenty

One owner per concern

Reminders live in 12. Playbook positions live with 02. The research store is shared by 05 and 20. When two workflows want the same capability, one of them calls the other.

Partial is a real status

Volume I gave you success and failed. Batch tools need a third: partial, with counts. Hermes can say "298 of 312 — 14 wouldn't open."

Log cost per execution

One 15 run can cost more than a month of everything else. Log tokens and duration per execution now, while the volume is small enough to fix cheaply.

Nothing new leaves the building

Across all twenty, exactly one tool sends outward mail — WF01's welcome email, to a client who just engaged. Everything else drafts, flags, or reports. Keep that ratio.

Test the collisions, not just the tools

Add one test per near-miss pair. Say "what's due next month?" and check Hermes reaches for check_roc_compliance and not compute_deadlines. Ambiguous phrasing should make it ask which you meant — a clarifying question is the correct answer, not a failure.

Corrections

Errata for v1.0

Small fixes to the Volume I guide, found while reviewing it. None are architectural — the shape of that document is sound — but a few will cost a reader an afternoon.

WhereIssueFix
Step 03 · endpoint URL Only the production path is shown, but the text tells you to use the Test URL while building. n8n's test path is /mcp-test/<id>; production is /mcp/<id>. This is the exact cause of the "Hermes sees no tools" symptom in the troubleshooting table.
Step 03 · MCP config "transport": "sse" pins Hermes to the older transport. Current n8n also serves Streamable HTTP, which is where MCP is heading. Note both so the agent config isn't stuck.
Step 04 · node name "Custom n8n Workflow Tool" no longer matches the palette. Search for Call n8n Sub-Workflow Tool.
Step 02 · docker run -it --rm contradicts both the upgrade instructions and the Compose file's restart: unless-stopped. Use -d --restart unless-stopped. The volume protects your data either way; --rm just throws away the container config.
Step 04 · return shape "Return a single structured JSON object" — but sub-workflows return an array of items. End every sub-workflow with a Set or Code node emitting exactly one item, or Hermes receives a list it has to flatten.
Page script · copy buttons navigator.clipboard is called with no .catch(); on file:// it can reject silently and the button appears dead. Add a fallback path — this page does, and shows "select & copy" when the API is unavailable.
Page script · scroll-spy offsetTop is measured against offsetParent, so it breaks if any ancestor gains position:relative. Use getBoundingClientRect().top. This page's spy does.
Still the two best lines in Volume I

"If it involves judgement, wording, or talking to the lawyer → Hermes. If it involves moving data, calling an API, or waiting → n8n." And: always return a friendly failure object, never a raw error. Those two rules are what make a twenty-tool gateway survivable.